package it.unitn.testbed.client;

import it.unitn.testbed.client.panels.SetupPanel;
import it.unitn.testbed.client.panels.TaskPanel;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TabPanel;

/**
 * {@code Testbed} is the main class of the client Ajax GUI.
 * 
 * It consists of a {@code TabPanel}, i.e. {@link Testbed#tabs}, and of a status
 * label, i.e. {@link Testbed#statusLabel}, where the various tabs can display
 * output messages.
 * 
 * All of the remote calls are handled by
 * {@link it.unitn.testbed.server.TestbedServiceImpl}.
 * 
 * @author Stefan Guna
 * @see it.unitn.testbed.client.panels
 * @see it.unitn.testbed.server.TestbedServiceImpl
 */
public class Testbed implements EntryPoint {
	/** The minimum height allowed for main tab panel ({@link Testbed#tabs}). */
	private static final int MIN_HEIGHT = 400;
	/** The status label */
	private Label statusLabel = new Label("Idle.");
	/**
	 * The main tab panel where panels from
	 * {@link it.unitn.testbed.client.panels} are plugged
	 */
	private TabPanel tabs;
	/**
	 * The taskPanel is needed here because it needs to be rebuilt every time a
	 * task is submitted.
	 */
	private TaskPanel taskPanel;

	/** GWT RPC client that calls methods on the server side. */
	private TestbedServiceAsync testbedService = GWT
			.create(TestbedService.class);

	/**
	 * Getter for {@link #testbedService}.
	 * 
	 * @return The GWT RPC client.
	 */
	public TestbedServiceAsync getTestbedService() {
		return testbedService;
	}

	/**
	 * Replaces the current task panel ({@link Testbed#taskPanel} with a new
	 * instance.
	 * 
	 * @param selectIt
	 *            Flag whether the new task panel should get focus.
	 * @see TaskPanel
	 */
	public void newTaskPanel(boolean selectIt) {
		int idx = tabs.getWidgetIndex(taskPanel);
		taskPanel = new TaskPanel(this);
		tabs.insert(taskPanel, "Task", idx);
		tabs.remove(idx + 1);
		if (selectIt)
			tabs.selectTab(idx);
	}

	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {
		tabs = new TabPanel();
		tabs
				.setWidth(new Integer((int) (Window.getClientWidth() * 0.9))
						+ "px");
		int tabHeight = (int) (Window.getClientHeight() - 100);
		if (tabHeight < MIN_HEIGHT)
			tabHeight = MIN_HEIGHT;
		tabs.setHeight(new Integer(tabHeight) + "px");

		Window.addResizeHandler(new ResizeHandler() {
			public void onResize(ResizeEvent event) {
				tabs.setWidth(new Integer((int) (event.getWidth() * 0.9))
						+ "px");
				int tabHeight = (int) (event.getHeight() - 100);
				if (tabHeight < MIN_HEIGHT)
					tabHeight = MIN_HEIGHT;
				tabs.setHeight(new Integer(tabHeight) + "px");
			}
		});

		DockPanel mainPanel = new DockPanel();
		statusLabel.setHeight("1em");

		taskPanel = new TaskPanel(this);
		tabs.add(taskPanel, "Task");
		tabs.add(new SetupPanel(this), "Setup");

		tabs.selectTab(0);

		mainPanel.add(tabs, DockPanel.CENTER);
		mainPanel.add(statusLabel, DockPanel.SOUTH);

		RootPanel.get("testbedMain").add(mainPanel);
	}

	/**
	 * Sets the status label.
	 * 
	 * @param text
	 *            String to display on the status label.
	 */
	public void setStatus(String text) {
		statusLabel.setText(text);
	}
}
